Modularisation and Parameterisation
Reusability and maintenance are key requirements of a successful test automation solution, therefore being able to quickly build frameworks and adapting the frameworks to change is essential.
Within Eggplant, this is a fundamental best practice to ensure concise and sustainable scripts are created whilst also ensuring a simple approach to automation in Eggplant is followed.
The rules to follow when building out modular functionality can be broken down in to 3 rules of thumb:- Identify Reoccurring Scenarios
- Reusing Functions Within Functions
- Simplifying Approaches
DO: ✅
- Add parameters to the function to make the function more reusable
- Limit handlers to specific functionality
- Break it down for specific groups of behaviours (e.g. handler for launch browser, handler for login, handler for navigating through the main menu)
- Don't over-engineer the solution - We don't need parameters for everything!
- Don't include actions for a whole flow into one handler (e.g. handler for 'start test' that incorporates all of the separate actions)
Identifying Reoccurring Scenarios
Using the example of our code from earlier best practices (shown below), we can determine that there is 3 key functionality that is repeating through the use case.
- Launching The Browser
- Dropdown and Navigate
- Navigating on Page
click image:"chrome" // Icon
waitfor 20, image:"refresh" // Icon
set the searchRectangle to (0,70,1920,1039) // Optimises OCR
typetext "https://demo.nopcommerce.com/",returnkey
waitfor 20, image:"nopCommerce" // Logo
moveto text:"Computers"
wait 1 // Optimises OCR
click text:"Desktops"
wait 1.5 // Optimises OCR
waitfor 20, text:"Categories"
click text:"Digital Storm VANQUISH 3"
wait 1.5 // Optimises OCR
waitfor 20, text:"Digital Storm Vanquish 3 Desktop PC"
click text:"ADD TO CART"
wait 2 // Optimises OCR
waitfor 20,text:"The product has been added to your shopping cart"
click image:"chrome" // Icon
waitfor 20, image:"refresh" // Icon
set the searchRectangle to (0,70,1920,1039) // Optimises OCR
typetext "https://demo.nopcommerce.com/",returnkey
waitfor 20, image:"nopCommerce" // Logo
moveto text:"Computers"
wait 1 // Optimises OCR
click text:"Desktops"
wait 1.5 // Optimises OCR
waitfor 20, text:<mark>"Categories"</mark>
click text:"Digital Storm VANQUISH 3"
wait 1.5 // Optimises OCR
waitfor 20, text:"Digital Storm Vanquish 3 Desktop PC"
click text:"ADD TO CART"
wait 2 // Optimises OCR
waitfor 20,text:"The product has been added to your shopping cart"
Using the breakdown of the script above, building out a navigation function and referencing it would look like the following:
Navigate Function: | Calling the Function: | |
---|---|---|
|
|
If any changes need to be made to the Navigate flow, a user will need to make only one change, rather than trying to update the occurrences of the functionality across the scripts.
Creating a reoccurring function, allows for a consistent understanding of the automation behaviour and consistency across the script.
Reusing Functions Within Functions
The use case requires the 'drop down' functionality, and as this is likely to be repeated in further use cases, it makes sense to build this out as a reusable function.
Breaking down the UI interaction, a user would move to the menu and select an option from the dropdown - which can be partially facilitated using the navigate function already created.
Drop Down Function: | Calling the Function: | |
---|---|---|
|
|
Using the functions like 'Lego', accelerates the generation of the framework.
Simplifying Approaches
The final function is to 'launch a browser' to the webpage. While this is being only called once in the example use case - it may be that a broader requirement is cross browser testing or the use cases may lead to other webpages.
For that, we've built a function for launching a browser and parameterised the browser and url:
Original Launch Browser Function: | Calling the Function: | |
---|---|---|
|
|
Simpler / Cheaper Alternatives To Scripts
Outside our rules of thumb, it is good practice to look back and ensure any function is the simplest it could be.
Key aspects to consider are:- What if the SUT / AUT change.
- What if we need to extend the test pack - Will the approach need adapting / will it need updating or extending?
- How can we avoid capturing test assets of the system not involved in testing i.e. Operating System UIs / Browser UIs etc.
A good example of this is the Launch Browser Script. Currently to run this against chrome, we have caught an image of the Chrome Icon, we then validate Chrome has launched by capturing the refresh button.
What if we wanted to include extend the testing to Firefox and Edge? We would require 4 new images to be captured(icons and refresh buttons per browser). This may seem like a small overhead, however if this function represents the overall approach we've taken, then it would suggest a high maintenance cost which is easily avoidable.
A solution would be to utilise built in SUT functionality, like the 'Windows Run' window and launch the Browser straight to the URL and validate with the AUT logo, in this case the NopCommerce logo.
Here we have significantly reduced the number of test assets (browser icon and browser refresh button) captured outside the test scope.
Original Launch Browser Function | Updated Launch Browser Function | |
---|---|---|
|
|
A Summary of What You Have Learned
A fundamental best practice of automation development, is to ensure that the scripts are as modular and reusable as possible. Grouping reoccurring functionality and simplifying the code using parameters ensure that the scripts are more maintainable.
// Step 1
click image:"chrome" // Icon
waitfor 20, image:"refresh" // Icon
set the searchRectangle to (0,70,1920,1039) // Optimises OCR
typetext "https://demo.nopcommerce.com/",returnkey
waitfor 20, image:"nopCommerce" // Logo
// Step 2
moveto text:"Computers"
wait 1 // Optimises OCR
click text:"Desktops"
wait 1.5 // Optimises OCR
waitfor 20, text:"Categories"
// Step 3
click text:"Digital Storm VANQUISH 3"
wait 1.5 // Optimises OCR
waitfor 20, text:"Digital Storm Vanquish 3 Desktop PC"
// Step 4
click text:"ADD TO CART"
wait 2 // Optimises OCR
waitfor 20,text:"The product has been added to your shopping cart"
// Step 5
moveto image:"Basket"
wait 1
click text:"GO TO CART"
wait 2 // Optimises OCR
waitfor 20, text:"Shopping Cart"
assert that imagefound(0,text:"Digital Storm VANQUISH 3 Custom Performance PC")
// Step 1
launchBrowser ("chrome"),("https://demo.nopcommerce.com/")
set the searchRectangle to (0,70,1920,1039)
// Step 2
dropDown ("Computers"),("Desktops"),("Categories")
// Step 3
navigate ("Digital Storm VANQUISH 3"),("Digital Storm Vanquish 3 Desktop PC")
// Step 4
navigate ("ADD TO CART"),("The product has been added to your shopping cart")
// Step 5
dropDown ("Shopping cart"),("GO TO CART"),("Shopping Cart")
// END
// function to launch browser
to launchBrowser browser,url
set global browser to browser
typetext windowskey,"r"
wait 1
typetext browser&&url,returnkey
waitfor 20, image:"logos" // LOGO
end launchBrowser
// function that moves to and initiates dropdown
to dropDown menu,action,validation
moveto text:menu,searchRectangle:config().browser.(global browser)
wait 1
navigate (action),(validation)
end dropDown
// function to navigate using action and validation framework
to navigate action,validation
click text:action,searchRectangle:config().browser.(global browser)
wait 1.5 // page transition
waitfor 20, text:validation,searchRectangle:config().browser.(global browser)
end navigate